/* Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.luxor.commons.workflow.config.properties;

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import org.activiti.engine.impl.history.HistoryLevel;
import org.luxor.commons.core.config.properties.ThreadPoolProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.core.io.support.ResourcePatternResolver;

import java.util.Arrays;
import java.util.List;

/**
 * 工作流配置属性
 *
 * @author Mr.Yan  @date: 2021/10/15
 */
@ConfigurationProperties(WorkflowProperties.PREFIX)
public class WorkflowProperties {
    public static final String PREFIX = "spring.workflow";

    private final ThreadPoolProperties DEFAULT_THREAD_POOL = new ThreadPoolProperties();
    private final String DEFAULT_TABLE_PREFIX = "act_";
    private final String DEFAULT_DATASOURCE = "master";

    /**
     * 流程部署名称
     */
    private String deploymentName;

    /**
     * 数据源指定
     */
    private String dataSource;

    /**
     * 数据源类型指定
     */
    private String databaseSchema;

    /**
     * 建表规则
     * <p>
     * false： 默认值,不错任何操作。
     * true： 启动时会对数据库中所有表进行更新操作。如果表不存在，则自动创建。
     * create_drop： 启动时创建表，在关闭时删除表（必须手动关闭引擎，才能删除表）。
     * drop-create： 启动时删除原来的旧表，然后在创建新表（不需要手动关闭引擎）
     */
    private String databaseSchemaUpdate;

    /**
     * 检测历史表是否存在
     */
    private boolean dbHistoryUsed;

    /**
     * 启动自动部署
     */
    private boolean checkProcessDefinitions;

    /**
     * 部署模式
     * default：默认值,将所有资源分组到一个部署中，并对该部署应用重复过滤。
     * single-resource：为每个单独的资源创建一个单独的部署，并对该部署应用重复过滤。
     * resource-parent-folder: 为共享相同父文件夹的资源创建单独的部署，并对该部署应用重复过滤。
     * fail-on-no-process:
     * never-fail
     */
    private String deploymentMode;

    /**
     * 启用Redis分布式缓存
     */
    private boolean redisCacheEnable;

    /**
     * 将当前任务变量复制到下一任务的本地变量中
     */
    private boolean copyVariablesToLocalForTasks;

    /**
     * 自定义流程文件前缀
     */
    private String processDefinitionLocationPrefix;
    /**
     * 自定义流程文件后缀
     */
    private List<String> processDefinitionLocationSuffixes;

    /**
     * 记录历史等级 可配置的历史级别有none, acitivity, audit, all
     */
    private HistoryLevel historyLevel;

    /**
     * 使用json格式存储变量?
     */
    private boolean serializePOJOsInVariablesToJson;
    private String javaClassFieldForJackson;

    /**
     * 字体
     */
    private String fontName;

    /**
     * 线程池配置
     */
    @NestedConfigurationProperty
    private ThreadPoolProperties threadPool;

    /**
     * 启动异步线程池，执行工作流任务
     */
    private boolean asyncExecutorActivate;

    public WorkflowProperties() {
        this.threadPool = DEFAULT_THREAD_POOL;
        this.dataSource = DEFAULT_DATASOURCE;

        this.checkProcessDefinitions = true;
        this.asyncExecutorActivate = false;
        this.deploymentName = "SpringAutoDeployment";
        this.redisCacheEnable = true;
        this.databaseSchemaUpdate = "false";
        this.dbHistoryUsed = false;
        this.historyLevel = HistoryLevel.AUDIT;
        this.processDefinitionLocationPrefix = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + "**/processes/";
        this.processDefinitionLocationSuffixes = Arrays.asList("**.bpmn20.xml", "**.bpmn");
        this.copyVariablesToLocalForTasks = false;
        this.deploymentMode = "default";
        this.serializePOJOsInVariablesToJson = true;
        this.javaClassFieldForJackson = JsonTypeInfo.Id.CLASS.getDefaultPropertyName();
        this.fontName = "宋体";
    }

    public ThreadPoolProperties getThreadPool() {
        return threadPool;
    }

    public void setThreadPool(ThreadPoolProperties threadPool) {
        this.threadPool = threadPool;
    }

    public String getDataSource() {
        return dataSource;
    }

    public void setDataSource(String dataSource) {
        this.dataSource = dataSource;
    }

    public boolean isAsyncExecutorActivate() {
        return asyncExecutorActivate;
    }

    public void setAsyncExecutorActivate(boolean asyncExecutorActivate) {
        this.asyncExecutorActivate = asyncExecutorActivate;
    }

    public boolean isCheckProcessDefinitions() {
        return checkProcessDefinitions;
    }

    public void setCheckProcessDefinitions(boolean checkProcessDefinitions) {
        this.checkProcessDefinitions = checkProcessDefinitions;
    }

    public String getDeploymentName() {
        return deploymentName;
    }

    public void setDeploymentName(String deploymentName) {
        this.deploymentName = deploymentName;
    }

    public String getDatabaseSchemaUpdate() {
        return databaseSchemaUpdate;
    }

    public void setDatabaseSchemaUpdate(String databaseSchemaUpdate) {
        this.databaseSchemaUpdate = databaseSchemaUpdate;
    }

    public String getDatabaseSchema() {
        return databaseSchema;
    }

    public void setDatabaseSchema(String databaseSchema) {
        this.databaseSchema = databaseSchema;
    }

    public boolean isDbHistoryUsed() {
        return dbHistoryUsed;
    }

    public void setDbHistoryUsed(boolean isDbHistoryUsed) {
        this.dbHistoryUsed = isDbHistoryUsed;
    }

    public HistoryLevel getHistoryLevel() {
        return historyLevel;
    }

    public void setHistoryLevel(HistoryLevel historyLevel) {
        this.historyLevel = historyLevel;
    }

    public String getProcessDefinitionLocationPrefix() {
        return processDefinitionLocationPrefix;
    }

    public void setProcessDefinitionLocationPrefix(
            String processDefinitionLocationPrefix) {
        this.processDefinitionLocationPrefix = processDefinitionLocationPrefix;
    }

    public List<String> getProcessDefinitionLocationSuffixes() {
        return processDefinitionLocationSuffixes;
    }

    public void setProcessDefinitionLocationSuffixes(
            List<String> processDefinitionLocationSuffixes) {
        this.processDefinitionLocationSuffixes = processDefinitionLocationSuffixes;
    }

    public boolean isCopyVariablesToLocalForTasks() {
        return copyVariablesToLocalForTasks;
    }

    public void setCopyVariablesToLocalForTasks(boolean copyVariablesToLocalForTasks) {
        this.copyVariablesToLocalForTasks = copyVariablesToLocalForTasks;
    }

    public String getDeploymentMode() {
        return deploymentMode;
    }

    public void setDeploymentMode(String deploymentMode) {
        this.deploymentMode = deploymentMode;
    }

    public boolean isRedisCacheEnable() {
        return redisCacheEnable;
    }

    public void setRedisCacheEnable(boolean redisCacheEnable) {
        this.redisCacheEnable = redisCacheEnable;
    }

    public boolean isSerializePOJOsInVariablesToJson() {
        return serializePOJOsInVariablesToJson;
    }

    public void setSerializePOJOsInVariablesToJson(boolean serializePOJOsInVariablesToJson) {
        this.serializePOJOsInVariablesToJson = serializePOJOsInVariablesToJson;
    }

    public String getJavaClassFieldForJackson() {
        return javaClassFieldForJackson;
    }

    public void setJavaClassFieldForJackson(String javaClassFieldForJackson) {
        this.javaClassFieldForJackson = javaClassFieldForJackson;
    }

    public String getFontName() {
        return fontName;
    }

    public void setFontName(String fontName) {
        this.fontName = fontName;
    }
}
